#include "pool.h"
#include "ring_pool.h"

int CRingPool::Init(int iThrd)
{
	return Init(iThrd,3);
}

int CRingPool::Init(int iThrd, int iQueue)
{
    int iRet = -1;
    int iResult, iTmp;
    int i;
    CRingNode* pclNew = NULL;

    if (iThrd < 1 || iQueue < 1) SET_RET_AND_GOTO_EXIT(COMMON_ERR_INVALIDARGS);
    if (IsInit()) SET_RET_AND_GOTO_EXIT(COMMON_ERR_INITED);

    m_pclRing = new CRingNode();
    iResult = m_pclRing->Init(iQueue);

    for (i = 1; i < iThrd; i++)
    {
        pclNew = new CRingNode();
        iResult = pclNew->Init(iQueue);
        m_pclRing->Insert(pclNew);
    }

    iRet = 0;
_Exit:
    return iRet;
}

int CRingPool::Start()
{
    int iRet = -1;
    int iResult, iTmp;
    CRingNode* pclNode = m_pclRing;

    if (IsInit() == 0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_UNINITED);
    if (IsRunning()) SET_RET_AND_GOTO_EXIT(COMMON_ERR_STATE);

    do {
        iResult = pclNode->Start();
        if(iResult<0) SET_RET_AND_GOTO_EXIT(iResult);
        pclNode = pclNode->m_pclNext;
    } while (pclNode != m_pclRing);

    iRet = 0;
_Exit:
    if (iRet < 0) Stop();
    return iRet;
}

int CRingPool::IsRunning()
{
    if (IsInit() == 0) return COMMON_ERR_UNINITED;
    return m_pclRing->IsRunning();
}

int CRingPool::Stop()
{
    int iRet = -1;
    int iResult, iTmp;
    CRingNode* pclNode = m_pclRing;

    if (IsInit() == 0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_UNINITED);

    do {
        iResult = pclNode->Stop();
        pclNode = pclNode->m_pclNext;
    } while (pclNode != m_pclRing);

    iRet = 0;
_Exit:
    return iRet;
}

int CRingPool::AddTask(IThrdTask* pobjTask)
{
    int iRet = -1;
    //int iResult, iTmp;

    if (IsInit() == 0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_UNINITED);
    if (IsRunning() == 0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_STATE);

    iRet = m_pclRing->AddTask(pobjTask);
    m_pclRing = m_pclRing->m_pclNext;

_Exit:
    return iRet;
}

int CRingPool::Construct()
{
    m_pclRing = NULL;
    return 0;
}

int CRingPool::Destruct()
{
    Stop();

    return 0;
}

int CRingNode::Init(int iQueue)
{
    m_pclPrev = m_pclNext = this;
    return CT1Pool::Init(iQueue);
}

int CRingNode::Insert(CRingNode* data, int iPos)
{
    CRingNode* pclNext = NULL;

    if (iPos == 0)
    {
        pclNext = m_pclNext;
        m_pclNext = data;
        data->m_pclPrev = this;
        data->m_pclNext = pclNext;
        pclNext->m_pclPrev = data;
    }
    else if (iPos > 0)
    {
        pclNext = this;
        for (int i = 0; i < iPos; i++) pclNext = pclNext->m_pclNext;
        m_pclNext->Insert(data);
    }
    else//if(iPos < 0)
    {
        pclNext = this;
        for (int i = 0; i > iPos; i--) pclNext = pclNext->m_pclPrev;
        m_pclNext->Insert(data);
    }
    return 0;
}
